package com.buttlever;

import com.ChessUtils.JugWinLoseUtil;
import com.beans.*;
import com.ChessUtils.ChessUtil;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;


import java.io.File;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

/**
 * 对战版的功能绑定
 * @author acoffee
 * @create 2021-09-01 21:32
 */
public class ButtleButtonService implements Runnable {
    // 换边
    private char playSides = 'B';
    //储存棋子的数组
    private List<Chess> chesses = new ArrayList();
    //记录棋子的数量
    private int chessCount = 0;
    //是否胜利
    private boolean Win = false;

    //控制游戏状态,避免重复落子
    private boolean canPlay = true;
    //控制悔棋
    private boolean canRegret = false;

    private ButtleGoBangView buttleGoBangView;

    //定义一些组件的参数
    public int  chess_Size = 40;

    public ButtleButtonService(ButtleGoBangView buttleGoBangView) {
        this.buttleGoBangView = buttleGoBangView;
    }


    public void Click(Pane pane, int PaneLength, int SceneLength) {

        //给画板绑定鼠标点击事件
        pane.setOnMouseClicked(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                //获取到鼠标点击的真实坐标(x,y)
                int x = ((int) event.getX() - PaneLength + PaneLength / 2) / PaneLength;
                int y = ((int) event.getY() - PaneLength + PaneLength / 2) / PaneLength;

                //判断是否胜利了
                if (Win || !JugWinLoseUtil.ChessLegal(x, y, PaneLength, SceneLength, chessCount, chesses) || !canPlay) {
                    return;
                }

                drawChess(pane, x, y, true);
            }
        });
    }

    //为悔棋按钮添加功能
    public void RegretBtnAction(Button RegretBtn) {
        RegretBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

                if (canRegret) {
                    ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.REGRET), buttleGoBangView);
                } else {
                    ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.INFORMATION, "悔棋", "现在已经不能悔棋了！");
                }


            }
        });
    }

    //新局按钮
    public void newGameButtonAction(Button NewGameBtn, Pane pane) {
        NewGameBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

                boolean isNew = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "新局", "点击确认，开启新局");

                if (isNew) {
                    ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.NEWGAME), buttleGoBangView);
                }
            }
        });
    }

    //为退出功能添加功能
    public void ExitBtnAcition(Button ExitBtn) {
        ExitBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

                //在棋局结束条件下才可以选择自主退出，在棋局进行中需要征得别人的同意才能退出
                if (Win) {
                    //选择是否退出
                    boolean isExit = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "退出", "点击确认，即可退出！");
                    if (isExit) {
                        ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.EXIT_FORCE), buttleGoBangView);
                        System.exit(0);
                    }
                } else {
                    boolean isExit = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "退出", "点击确定,发送退出请求！");
                    if (isExit) {
                        ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.EXIT), buttleGoBangView);
                    }
                }
            }
        });
    }

    //为打谱按钮添加功能
    public void ReGameBtnAction(Button ReGameBtn, Pane pane, int PaneLength) {

        ReGameBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                boolean isLose = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "认输", "你确定认输吗？");
                if(isLose && !Win){
                    ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.IS_LOSE), buttleGoBangView);
                    Win = true;
                    canPlay = false;
                    canRegret = false;
                }
            }
        });
    }

    //为保存棋谱添加功能
    public void SaveGameBtnAction(Button SaveGameBtn) {

        SaveGameBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

                //让文件选择器，在本窗体弹出
                File file = ChessUtil.FileChoose("保存棋谱").showSaveDialog(buttleGoBangView);

                if (file == null) {
                    return;
                }

                for (Chess chess : chesses) {
                    String context = chess.getX() + "," + chess.getY() + "," + chess.getColor();
                    ChessUtil.write(context, file);
                }
            }
        });
    }

    //画棋子
    public void drawChess(Pane pane, int x, int y, boolean isSend) {

        Chess chess;
        Circle circle;
        //创建圆圈对象
        if (playSides == 'B') {
            circle = new Circle(x * chess_Size + chess_Size,
                    y * chess_Size + chess_Size, chess_Size / 4, Color.BLACK);
            chess = new Chess(x, y, Color.BLACK);
        } else {
            circle = new Circle(x * chess_Size + chess_Size,
                    y * chess_Size + chess_Size, chess_Size / 4, Color.WHITE);
            chess = new Chess(x, y, Color.WHITE);
        }

        chesses.add(chess);
        chessCount++;

        //将圆圈放到画板上
        pane.getChildren().add(circle);

        canRegret = true;

        //将棋子推送给对方
        if (isSend) {
            //只要将棋子推送过去我就不能落子了
            canPlay = false;
            ChessMessage message = new ChessMessage(x, y);
            ChessUtil.sendMsg(message, buttleGoBangView);
        }

        if (JugWinLoseUtil.WinGame(chess, chessCount, chesses)) {

            String str = playSides == 'B' ? "黑棋获胜!" : "白棋获胜!";

            //胜利提示
            ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, str, "点击确定关闭对话框");
            canPlay = false;
            Win = true;
        }

        //换边
        playSides = JugWinLoseUtil.ChangeSides(playSides);
    }

    //开启线程
    @Override
    public void run() {

        ServerSocket chessServer = null;
        try {
            //得到单例对象
            SourceDataSingle instance = SourceDataSingle.getInstance();

            chessServer = new ServerSocket(Integer.parseInt(instance.getSourcePort()));

            while (true) {
                Socket socket = chessServer.accept();

                //使用对象流对棋子信息进行解析
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

                //获取棋子信息
                Message chessMes = (Message) ois.readObject();

                System.out.println(chessMes.toString());

                //刷新界面
                updateUI(chessMes);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //初始化棋子
    public void initializeChess(Pane pane) {
        pane.getChildren().removeIf(new Predicate<Object>() {
            @Override
            public boolean test(Object t) {
                return t instanceof Circle;
            }
        });

        //将棋子容器初始化
        canPlay = true;
        chesses = new ArrayList<Chess>();
        chessCount = 0;
        Win = false;
        playSides = 'B';
    }


    //刷新页面
    public void updateUI(Message msg) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                if (msg instanceof ChessMessage) {
                    canPlay = true;
                    ChessMessage cMes = (ChessMessage) msg;
                    drawChess(buttleGoBangView.pane, cMes.getX(), cMes.getY(), false);
                } else if (msg instanceof ArgeeMessage) {
                    ArgeeMessage argeeMessage = (ArgeeMessage) msg;
                    switch (argeeMessage.getStatus()) {
                        //发送新局请求
                        case NEWGAME:
                            boolean isNew = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "新局", "是否同意开新局？");
                            if (isNew) {

                                initializeChess(buttleGoBangView.pane);

                                //返回信息
                                ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.NEWGAME_OK), buttleGoBangView);
                            }
                            break;

                        //返回 同意开新局的 通知
                        case NEWGAME_OK:
                            initializeChess(buttleGoBangView.pane);
                            ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.INFORMATION, "", "对方已同意开启新局！");
                            break;

                        //发送悔棋请求
                        case REGRET:
                            if(canPlay) {
                                boolean isRegret = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "悔棋", "是否同意对方悔棋？");
                                if (!Win && chesses.size() > 0 && isRegret) {
                                    buttleGoBangView.pane.getChildren().remove(buttleGoBangView.pane.getChildren().size() - 1);
                                    playSides = playSides == 'B' ? 'W' : 'B';
                                    chesses.remove(chesses.size() - 1);
                                    chessCount--;
                                    canRegret = false;
                                    canPlay = false;
                                    ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.REGRET_OK), buttleGoBangView);
                                }
                            }
                            break;

                        case REGRET_OK:
                            buttleGoBangView.pane.getChildren().remove(buttleGoBangView.pane.getChildren().size() - 1);
                            playSides = playSides == 'B' ? 'W' : 'B';
                            chesses.remove(chesses.size() - 1);
                            chessCount--;
                            canRegret = false;
                            canPlay = true;
                            break;

                        case IS_LOSE:
                            ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.INFORMATION, "", "对方已认输！");
                            canPlay = false;
                            canRegret = false;
                            Win = true;
                            break;

                        //发送退出请求
                        case EXIT:
                            boolean isExit = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "你太强了，对方想跑路", "是否同意？");

                            //对方同意退出就退出
                            if (isExit) {
                                ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.INFORMATION, "你胜利了", "");
                                ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.EXIT_OK), buttleGoBangView);
                                System.exit(0);
                            } else {
                                ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.EXIT_NO), buttleGoBangView);

                            }
                            break;

                        //同意退出自己也退出
                        case EXIT_OK:
                            System.exit(0);
                            break;

                        //对方不同意退出，你可以选择是否强制退出
                        case EXIT_NO:
                            boolean isForceExit = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.CONFIRMATION, "对方拒绝了你的请求", "是否强制退出！！");
                            if (isForceExit) {
                                ChessUtil.sendMsg(new ArgeeMessage(MessageEnum.EXIT_FORCE), buttleGoBangView);
                                System.exit(0);
                            }
                            break;

                        //当对方强制退出后，返回对方已退出的通知，点击确定退出
                        case EXIT_FORCE:
                            boolean Exit = ChessUtil.getUpWindows(buttleGoBangView, Alert.AlertType.INFORMATION, "对方已经退出！", "点击确定即可退出");
                            if (Exit) {
                                System.exit(0);
                            }
                            break;
                    }
                }
            }
        });
    }
}
